/**
* TS Client (http://www.transparent.co.nz)
* Copyright (c) 2004 Transparent Systems Limited
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the /doc/LICENSE.txt
* This is the GNU General Public License Version 2 as published by the Free Software Foundation.
* You can download this program from <a href="http://sourceforge.com/projects/ts-client">http://sourceforge.com/projects/ts-client</a>
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License Version 2 for more details.
*
* You should have received a copy of the GNU General Public License
* Version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
/*
* Created on Dec 7, 2003
*
*/
package nz.co.transparent.client.gui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.JInternalFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JScrollPane;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
/**
* @author johnz
*
*/
public class ListMenuItem extends JScrollPane implements MenuElement {
/**
* Map with {InternalFrame name, JInternalFrame instance}
*/
private Map internalFrameMap = new HashMap(1);
private JList itemList = new JList();
private Vector itemVector = new Vector();
private MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager();
private JMenu previousMenu;
private JMenu nextMenu;
/**
*
*/
public ListMenuItem() {
super();
itemVector.add("Item 1");
itemVector.add("Item 2");
itemVector.add("Item 3 is wider");
itemVector.add("Item 4");
itemVector.add("Item 5");
itemVector.add("Item 6");
itemVector.add("Item 7");
itemVector.add("Item 8");
itemList.setListData(itemVector);
itemList.setBackground(Color.decode("#cccccc"));
itemList.setBorder(BorderFactory.createEmptyBorder(0,10,0,10));
itemList.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_SPACE) || (e.getKeyCode() == KeyEvent.VK_ENTER)) {
String internalFrameName = (String) itemList.getSelectedValue();
JInternalFrame internalFrame = (JInternalFrame) internalFrameMap.get(internalFrameName);
menuSelectionManager.clearSelectedPath();
internalFrame.toFront();
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
if (previousMenu != null) {
menuSelectionManager.clearSelectedPath();
previousMenu.doClick();
}
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
if (nextMenu != null) {
menuSelectionManager.clearSelectedPath();
nextMenu.doClick();
}
} else if (e.getKeyCode() == KeyEvent.VK_HOME) {
itemList.setSelectedIndex(0);
} else if (e.getKeyCode() == KeyEvent.VK_END) {
itemList.setSelectedIndex(itemList.getMaxSelectionIndex() -1);
}
}
});
itemList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
String internalFrameName = (String) itemList.getSelectedValue();
JInternalFrame internalFrame = (JInternalFrame) internalFrameMap.get(internalFrameName);
menuSelectionManager.clearSelectedPath();
internalFrame.toFront();
//internalFrame.requestFocus();
}
});
setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
getViewport().add(itemList);
}
/* (non-Javadoc)
* @see javax.swing.MenuElement#menuSelectionChanged(boolean)
*/
public void menuSelectionChanged(boolean isIncluded) {
}
/* (non-Javadoc)
* @see javax.swing.MenuElement#getComponent()
*/
public Component getComponent() {
return this;
}
/* (non-Javadoc)
* @see javax.swing.MenuElement#getSubElements()
*/
public MenuElement[] getSubElements() {
return new MenuElement[0];
}
/* (non-Javadoc)
* @see javax.swing.MenuElement#processKeyEvent(java.awt.event.KeyEvent, javax.swing.MenuElement[], javax.swing.MenuSelectionManager)
*/
public void processKeyEvent(
KeyEvent event,
MenuElement[] path,
MenuSelectionManager manager) {
if (event.getKeyCode() == KeyEvent.VK_DOWN) {
int selectedIndex = itemList.getSelectedIndex();
selectedIndex++;
if (selectedIndex > itemVector.size() - 1) {
selectedIndex = 0;
}
event.consume(); // Notice menuSelectionManager that we have consumed the event
itemList.setSelectedIndex(selectedIndex);
itemList.requestFocus();
} else if (event.getKeyCode() == KeyEvent.VK_UP) {
int selectedIndex = itemList.getSelectedIndex();
selectedIndex--;
if (selectedIndex < 0) {
selectedIndex = itemVector.size() -1;
}
event.consume(); // Notice menuSelectionManager that we have consumed the event
itemList.setSelectedIndex(selectedIndex);
itemList.requestFocus();
} else {
// Handle other keys like JMenuItem.processKey() does
MenuKeyEvent mke = new MenuKeyEvent(event.getComponent(), event.getID(),
event.getWhen(), event.getModifiers(),
event.getKeyCode(), event.getKeyChar(),
path, manager);
processMenuKeyEvent(mke);
}
}
/* (non-Javadoc)
* @see javax.swing.MenuElement#processMouseEvent(java.awt.event.MouseEvent, javax.swing.MenuElement[], javax.swing.MenuSelectionManager)
*/
public void processMouseEvent(
MouseEvent event,
MenuElement[] path,
MenuSelectionManager manager) {
}
/**
* Add internal frame to menu list
* @param internalFrame
*/
public void addInternalFrame(JInternalFrame internalFrame) {
internalFrameMap.put(internalFrame.getName(), internalFrame);
itemVector.add(internalFrame.getName());
Collections.sort(itemVector);
itemList.setListData(itemVector); // Refresh list
setListWidth();
}
/**
* Remove internal frame from menu list
* @param internalFrame
*/
public void removeInternalFrame(JInternalFrame internalFrame) {
internalFrameMap.remove(internalFrame.getName());
itemVector.remove(internalFrame.getName());
itemList.setListData(itemVector); // Refresh list
setListWidth();
}
/**
*
* @return Vector with internal frame names
*/
public Vector getInternalFrameNameList() {
return this.itemVector;
}
/**
* Handles a keystroke in a menu.
*
* @param e a <code>MenuKeyEvent</code> object
*/
private void processMenuKeyEvent(MenuKeyEvent e) {
// if (DEBUG) {
// System.out.println("in JMenuItem.processMenuKeyEvent for " + getText()+
// " " + KeyStroke.getKeyStrokeForEvent(e));
// }
switch (e.getID()) {
case KeyEvent.KEY_PRESSED:
fireMenuKeyPressed(e); break;
case KeyEvent.KEY_RELEASED:
fireMenuKeyReleased(e); break;
case KeyEvent.KEY_TYPED:
fireMenuKeyTyped(e); break;
default:
break;
}
}
/**
* Notifies all listeners that have registered interest for
* notification on this event type.
*
* @param event a <code>MenuKeyEvent</code>
* @see EventListenerList
*/
private void fireMenuKeyPressed(MenuKeyEvent event) {
// if (DEBUG) {
// System.out.println("in JMenuItem.fireMenuKeyPressed for " + getText()+
// " " + KeyStroke.getKeyStrokeForEvent(event));
// }
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==MenuKeyListener.class) {
// Lazily create the event:
((MenuKeyListener)listeners[i+1]).menuKeyPressed(event);
}
}
}
/**
* Notifies all listeners that have registered interest for
* notification on this event type.
*
* @param event a <code>MenuKeyEvent</code>
* @see EventListenerList
*/
private void fireMenuKeyReleased(MenuKeyEvent event) {
// if (DEBUG) {
// System.out.println("in JMenuItem.fireMenuKeyReleased for " + getText()+
// " " + KeyStroke.getKeyStrokeForEvent(event));
// }
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==MenuKeyListener.class) {
// Lazily create the event:
((MenuKeyListener)listeners[i+1]).menuKeyReleased(event);
}
}
}
/**
* Notifies all listeners that have registered interest for
* notification on this event type.
*
* @param event a <code>MenuKeyEvent</code>
* @see EventListenerList
*/
private void fireMenuKeyTyped(MenuKeyEvent event) {
// if (DEBUG) {
// System.out.println("in JMenuItem.fireMenuKeyTyped for " + getText()+
// " " + KeyStroke.getKeyStrokeForEvent(event));
// }
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==MenuKeyListener.class) {
// Lazily create the event:
((MenuKeyListener)listeners[i+1]).menuKeyTyped(event);
}
}
}
private void setListWidth() {
Iterator iterator = itemVector.iterator();
int maxSize = 0;
StringBuffer maxBuffer = new StringBuffer();
while (iterator.hasNext()) {
String name = (String) iterator.next();
if (name.length() > maxSize) {
maxSize = name.length();
maxBuffer.setLength(0);
maxBuffer.append(name);
}
}
Font font = itemList.getFont();
FontMetrics fontMetrics = itemList.getFontMetrics(font);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
int width = fontMetrics.stringWidth(maxBuffer.toString()) + 10;
width = Math.min(width, screen.width -100);
int rowCount = Math.min(itemVector.size(), 10);
itemList.setVisibleRowCount(rowCount);
itemList.setFixedCellWidth(width);
}
// public Dimension getPreferredSize() {
//
// Iterator iterator = itemVector.iterator();
// int maxSize = 0;
// StringBuffer maxBuffer = new StringBuffer();
// while (iterator.hasNext()) {
// String name = (String) iterator.next();
// if (name.length() > maxSize) {
// maxSize = name.length();
// maxBuffer.setLength(0);
// maxBuffer.append(name);
// }
// }
//
// Font font = itemList.getFont();
// FontMetrics fontMetrics = itemList.getFontMetrics(font);
// Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
// int width = fontMetrics.stringWidth(maxBuffer.toString()) + 20;
// width = Math.min(width, screen.width -100);
// int rowCount = Math.min(itemVector.size(), 10);
// itemList.setVisibleRowCount(rowCount);
// itemList.setFixedCellWidth(width);
// return itemList.getPreferredSize();
// }
/**
* Set previous menu
* @param previousMenu
*/
public void setPreviousMenu(JMenu previousMenu) {
this.previousMenu = previousMenu;
}
/**
* Set next menu
* @param nextMenu
*/
public void setNextMenu(JMenu nextMenu) {
this.nextMenu = nextMenu;
}
}